package registry

import (
	"strings"
	"wf-deploy-agent/conf"
	"wf-deploy-agent/infra"
	entity "wf-deploy-agent/registry/entity"
	zk "wf-deploy-agent/registry/zookeeper"
)

var reg = initRegistry()
var dis = initDiscovery()

func initRegistry() Registry {
	t := strings.ToLower(conf.CF.Registry.Type)
	if t == "zookeeper" {
		return zk.NewZkRegistry()
	}

	return zk.NewZkRegistry()
}

func initDiscovery() Discovery {
	t := strings.ToLower(conf.CF.Registry.Type)
	if t == "zookeeper" {
		return zk.NewZkDiscovery()
	}

	return zk.NewZkDiscovery()
}

func GetService(name string) []*entity.ServiceInstance {
	instances, err := dis.GetService(name)
	if err != nil {
		infra.Logger.Errorln(err)
		return []*entity.ServiceInstance{}
	}

	return instances
}

func GetInstance(name string, routingKey ...string) *entity.ServiceInstance {
	var err error
	var instance *entity.ServiceInstance
	if routingKey != nil && len(routingKey) > 0 {
		instance, err = dis.GetOrientedInstance(name, routingKey[0])
	} else {
		instance, err = dis.GetInstance(name)
	}

	if err != nil {
		infra.Logger.Errorln(err)
		return nil
	}

	return instance
}

func doFilter(instances []*entity.ServiceInstance, excludeHosts []string) []*entity.ServiceInstance {
	_instances := make([]*entity.ServiceInstance, 0)
	for _, i := range instances {
		for _, e := range excludeHosts {
			if i.GetHostName() != e {
				_instances = append(_instances, i)
			}
		}
	}

	return _instances
}

func GetAgents(excludeHosts ...string) []*entity.ServiceInstance {
	instances, err := dis.GetService(conf.CF.Agent.Service.Name)
	if err != nil {
		infra.Logger.Errorln(err)
		return []*entity.ServiceInstance{}
	}

	if excludeHosts != nil && len(excludeHosts) > 0 {
		return doFilter(instances, excludeHosts)
	}

	return instances
}

func GetSchedulers(excludeHosts ...string) []*entity.ServiceInstance {
	instances, err := dis.GetService(conf.CF.Scheduler.Name)
	if err != nil {
		infra.Logger.Errorln(err)
		return []*entity.ServiceInstance{}
	}

	if excludeHosts != nil && len(excludeHosts) > 0 {
		return doFilter(instances, excludeHosts)
	}

	return instances
}

func Start() {
	dis.Monitor()
	reg.Prepare()
}
